#Copyright (C) Nial Peters 2012
#
#This file is part of AvoScan.
#
#AvoScan is free software: you can redistribute it and/or modify
#it under the terms of the GNU General Public License as published by
#the Free Software Foundation, either version 3 of the License, or
#(at your option) any later version.
#
#AvoScan is distributed in the hope that it will be useful,
#but WITHOUT ANY WARRANTY; without even the implied warranty of
#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#GNU General Public License for more details.
#
#You should have received a copy of the GNU General Public License
#along with AvoScan.  If not, see <http://www.gnu.org/licenses/>.
"""
This module provides an interface for creating and editing field notes
templates.
"""
import wx

from avoscan.templates import TemplateManager


class TemplateEditorPanel(wx.Panel):
    """
    Panel for creating/deleting/editing field notes templates.
    """
    def __init__(self, parent):
        wx.Panel.__init__(self, parent)
        
        self.template_manager = TemplateManager()
        
        vsizer = wx.BoxSizer(wx.VERTICAL)
        selection_sizer = wx.BoxSizer(wx.HORIZONTAL)
        side_buttons_sizer = wx.BoxSizer(wx.VERTICAL)

        self.new_button = wx.Button(self, wx.ID_ANY, "New")
        self.edit_button = wx.Button(self, wx.ID_ANY, "Edit")
        self.delete_button = wx.Button(self, wx.ID_ANY, "Delete")
        side_buttons_sizer.Add(self.new_button, 0,
                               wx.ALL | wx.ALIGN_RIGHT, border=10)
        side_buttons_sizer.Add(self.edit_button, 0,
                               wx.LEFT | wx.RIGHT | wx.ALIGN_RIGHT, border=10)
        side_buttons_sizer.Add(self.delete_button, 0,
                               wx.ALL | wx.ALIGN_RIGHT, border=10)
        
        #set selection box to same height as buttons
        size = side_buttons_sizer.GetMinSize()
        self.template_names = []
        self.templates_list = wx.ListBox(self, wx.ID_ANY,
                                         choices=self.template_names,
                                         size=size)
        
        selection_sizer.Add(self.templates_list, 1,
                             wx.ALIGN_LEFT | wx.ALIGN_TOP | wx.ALL, border=10)
        selection_sizer.Add(side_buttons_sizer, 0,
                            wx.ALIGN_RIGHT | wx.ALL, border=10)
        
        vsizer.Add(selection_sizer, 0, wx.ALIGN_TOP | wx.EXPAND | 
                   wx.ALIGN_CENTER_HORIZONTAL)
        
        #add the editing box
        self.edit_box = wx.TextCtrl(self, wx.ID_ANY,
                                    style=wx.TE_MULTILINE | wx.TE_RICH)
        self.edit_box.Disable()#SetEditable(False)
        vsizer.Add(self.edit_box, 1 , wx.EXPAND | wx.ALL, border=10)
        
        #add the save and cancel buttons at the bottom
        buttons_sizer = wx.BoxSizer(wx.HORIZONTAL)
        self.save_button = wx.Button(self, wx.ID_ANY, "Save")
        self.cancel_button = wx.Button(self, wx.ID_ANY, "Cancel")
        self.save_button.Disable()
        self.cancel_button.Disable()
        buttons_sizer.Add(self.cancel_button, 0, wx.ALIGN_CENTER_HORIZONTAL)
        buttons_sizer.Add(self.save_button, 0, wx.ALIGN_CENTER_HORIZONTAL)
        
        vsizer.Add(buttons_sizer, 0, wx.ALIGN_CENTER_HORIZONTAL | 
                   wx.ALIGN_BOTTOM | wx.BOTTOM, border=20)
        
        wx.EVT_BUTTON(self, self.new_button.GetId(), self.on_new)
        wx.EVT_BUTTON(self, self.edit_button.GetId(), self.on_edit)
        wx.EVT_BUTTON(self, self.delete_button.GetId(), self.on_delete)
        wx.EVT_BUTTON(self, self.save_button.GetId(), self.on_save)
        wx.EVT_BUTTON(self, self.cancel_button.GetId(), self.on_cancel)
        wx.EVT_LISTBOX(self, self.templates_list.GetId(), self.on_list_box)
        self.edit_button.Disable()
        self.delete_button.Disable()
        self.update_templates_list()
        self.SetSizer(vsizer)
        vsizer.Fit(self)
        self.SetAutoLayout(1)
       
        
        
    def on_new(self, evnt):
        """
        Event handler for the New button.
        """
        d = wx.TextEntryDialog(self, "Enter new template name:")
        if d.ShowModal() == wx.ID_OK:
            try:
                self.template_manager.create_new_template(d.GetValue())
            except ValueError:
                wx.MessageBox("A template with that name already exists.",
                               "AvoScan", wx.ICON_ERROR)
                return 
            self.update_templates_list()
            self.edit_button.Disable()
            self.delete_button.Disable()
    
    
    
    def on_delete(self, evnt):
        """
        Event handler for the Delete button.
        """
        idx = self.templates_list.GetSelection()
        if idx == wx.NOT_FOUND:
            return
        name = self.template_names[idx]
        self.template_manager.delete_template(name)
        self.edit_box.SetValue("")
        self.update_templates_list()
        self.edit_button.Disable()
        self.delete_button.Disable()
    
    
    def on_edit(self, evnt):
        """
        Event handler for the Edit button.
        """
        self.new_button.Disable()
        self.edit_button.Disable()
        self.delete_button.Disable()
        self.templates_list.Disable()
        
        self.save_button.Enable()
        self.cancel_button.Enable()
        
        self.edit_box.Enable()#SetEditable(True)
    
    
    
    def on_list_box(self, evnt):
        """
        Event handler for selection events in the list of available templates.
        Loads the contents of the template and puts it into the editing
        panel.
        """    
        if self.template_names:
            idx = self.templates_list.GetSelection()
            if not idx == wx.NOT_FOUND:
                template_name = self.template_names[self.templates_list.GetSelection()]
                template_txt = self.template_manager.load_template(template_name)
                
                self.edit_box.SetValue(template_txt)
                
                self.edit_button.Enable()
                self.delete_button.Enable()
        
        
    
    def on_cancel(self, evnt):
        """
        Event handler for the Cancel button. Resets all the controls. This
        method is also called by the on_save() method.
        """
        self.edit_box.Disable()
        self.save_button.Disable()
        self.cancel_button.Disable()
        self.new_button.Enable()

        self.templates_list.Enable()
        self.edit_button.Enable()
        self.delete_button.Enable()
        
        #reload the template contents
        self.on_list_box(None)
    
    
    def on_save(self, evnt):
        """
        Event handler for the Save button. Saves the contents of the edit panel
        to a file and then calls the on_cancel() method to reset all the 
        controls.
        """
        new_template_text = self.edit_box.GetValue()
        template_name = self.template_names[self.templates_list.GetSelection()]
        self.template_manager.create_new_template(template_name,
                                                  contents=new_template_text,
                                                  force=True)
        self.on_cancel(None)
        
        
        
    def update_templates_list(self):
        """
        Reloads the list of available templates.
        """
        self.template_names = self.template_manager.get_template_names()
        self.templates_list.SetItems(self.template_names)
        if not self.template_names:
            self.edit_button.Disable()
            self.delete_button.Disable()
            
